﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using produccion.modelo;
using produccion.clases;
using System.Collections.ObjectModel;
using System.Windows;
using produccion.AccesoDatos;
using System.Windows.Media;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Input;
using System.Collections.Specialized;
using System.Data;




namespace produccion.vistamodelo
{
    public class VMReporteProcProd : ObservableObject, IDataErrorInfo
    {
        #region Constructor
        
        public VMReporteProcProd()
        {
            consultarRPP();
            consultarSemana("I");

            lisempleados = new CLSMAEEMPP().listaEmpleados();
            _buscarEmpleado = new VMbuscarGeneral((from emp in lisempleados select new
                VMlistaGenerica { strColumna1 = emp.CODEMP_EMP, strColumna2 = emp.CEDEMP_EMP, strColumna3 = emp.NOMEMP_EMP }).ToList());
            buscarEmpleado.PropertyChanged += OnBuscarEmpleadoPropertyChanged;
            buscarEmpleado.gridBuscar.columna1.strNombre = "Código";
            buscarEmpleado.gridBuscar.columna2.strNombre = "Identificación";
            buscarEmpleado.gridBuscar.columna3.strNombre = "Nombre";
            encRep.detOperario.CollectionChanged += OnCollectionChanged;

            encRep.listallas.CollectionChanged += OnCollectionChangedTallas;

            if (MDOgeneral.conexion == null || MDOgeneral.conexion.State == ConnectionState.Closed)
            {
                MDOgeneral.conectar();
            }
            strTituloVentana = "Reporte de procesos de producción - Usuario: " + MDOgeneral.usuario + " - [FRMReporteProcProd]";
        }
        #endregion

        #region comandos

        RelayCommand _cmdGuardar;
        public ICommand cmdGuardar
        {
            get
            {
                if (_cmdGuardar == null)
                {
                    _cmdGuardar = new RelayCommand(param => this.guardar() );
                }
                return _cmdGuardar;
            }
        }

        RelayCommand _cmdBuscarOperario;
        public ICommand cmdBuscarOperario
        {
            get
            {
                if (_cmdBuscarOperario == null)
                {
                    _cmdBuscarOperario = new RelayCommand(x => BuscaOperario());
                }
                return _cmdBuscarOperario;
            }
        }

        RelayCommand _cmdSalir;
        public ICommand cmdSalir
        {
            get
            {
                if (_cmdSalir == null)
                {
                    _cmdSalir = new RelayCommand(Salir);
                }
                return _cmdSalir;
            }
        }

        RelayCommand _cmdLostFocus;
        public ICommand cmdLostFocus
        {
            get
            {
                if (_cmdLostFocus == null)
                {
                    _cmdLostFocus = new RelayCommand(parame=> encRep.validarErrorOperario());
                }
                return _cmdLostFocus;
            }
        }
        #endregion comandos
        
        #region propiedades

        private ProcesoProduccionRepositorio _repositorio = new ProcesoProduccionRepositorio();

        private ObservableCollection<MReporteProcProd.opcion> _opciones = new ObservableCollection<MReporteProcProd.opcion>();
        public ObservableCollection<MReporteProcProd.opcion> opciones
        {
            get { return _opciones; }
            set { _opciones = value; RaisePropertyChangedEvent("opciones"); }
        }

        public MReporteProcProd.opcion selOpcion
        {
            get { return encRep.selOpcion; }
            set {
                encRep.detOperario.Clear();
                encRep.listallas.Clear();
                encRep.numTotalaReportar = 0;
         
                selOpcion.color = (Brush)new BrushConverter().ConvertFrom("#FFD7D7D7");
                encRep.selOpcion = value;
                if(!numConsecutivo.Equals(encRep.selOpcion.numConsecutivo.ToString()))
                {
                    numConsecutivo = encRep.selOpcion.numConsecutivo.ToString();
                }
                RaisePropertyChangedEvent("selOpcion"); }
        }

        private string _numConsecutivo="";
        public string numConsecutivo
        {
            get { return _numConsecutivo; }
            set
            {
                selOpcion.color = (Brush)new BrushConverter().ConvertFrom("#FFD7D7D7");
                _numConsecutivo = value;

                if (!String.IsNullOrEmpty(_numConsecutivo))
                {
                    int consec = Convert.ToInt32(_numConsecutivo) - 1;
                    if (consec >= 0 && consec < opciones.Count)
                    {
                        selOpcion = opciones[consec];
                        if (encRep.strNumeroOrden.Length > 5)
                        {
                            _repositorio.consultarOrden(encRep);
                            encRep.detOperario.Clear();
                            encRep.detOperario = new ObservableCollection<MReporteProcProd.operario>();
                            if (selOpcion.strPreasignado.Equals("S"))
                            {
                                _repositorio.consultarOperarioOrdPro(encRep);
                                encRep.logErrorOperarios = false;
                            }
                            else
                            {
                                encRep.logErrorOperarios = true;
                            }
                            _repositorio.consultarTallasOrdenPro(encRep);
                            _repositorio.consultarTotalesOrdenPro(encRep);
                      }
                        selOpcion.color = (Brush)new BrushConverter().ConvertFrom("#FFA1CFEA");
                    }
                }

                RaisePropertyChangedEvent("numConsecutivo");
            }
        }
        
        private MReporteProcProd.encabezado _encRep = new MReporteProcProd.encabezado();
        public MReporteProcProd.encabezado encRep
        {
            get { return _encRep; }
            set { _encRep = value; RaisePropertyChangedEvent("encRep"); }
        }

        private MReporteProcProd.operario _opeRep = new MReporteProcProd.operario();
        public MReporteProcProd.operario opeRep
        {
            get { return _opeRep; }
            set { _opeRep = value; RaisePropertyChangedEvent("opeRep"); }
        }
        
        public int numSemana
        {
            get { return encRep.numSemana; }
            set 
            { 
                encRep.numSemana = value;
                consultarSemana("S");   
                RaisePropertyChangedEvent("numSemana"); 
            }
        }
        
        public DateTime dtmDesde
        {
            get { return encRep.dtmDesde; }
            set { encRep.dtmDesde = value; RaisePropertyChangedEvent("dtmDesde"); }
        }
        
        public DateTime dtmHasta
        {
            get { return encRep.dtmHasta; }
            set 
            { 
                encRep.dtmHasta = value;
                consultarSemana("F");
                RaisePropertyChangedEvent("dtmHasta"); 
            }
        }

        public string strNumeroOrden
        {
            get { return encRep.strNumeroOrden; }
            set 
            { 
                encRep.strNumeroOrden = value;

                if (encRep.strNumeroOrden.Trim().Length > 5)
                {
                    _repositorio.consultarOrden(encRep);
                    encRep.detOperario.Clear();
                    encRep.detOperario = new ObservableCollection<MReporteProcProd.operario>();
                    if (selOpcion.strPreasignado.Equals("S"))
                    {
                        _repositorio.consultarOperarioOrdPro(encRep);
                        encRep.logErrorOperarios = false;
                    }
                    else
                    {
                        encRep.logErrorOperarios = true;
                    }
                    _repositorio.consultarTallasOrdenPro(encRep);
                    _repositorio.consultarTotalesOrdenPro(encRep);
                    RaisePropertyChangedEvent("encRep");
                }
                else
                {
                    limpiarOrden();
                }
                RaisePropertyChangedEvent("strNumeroOrden");
                RaisePropertyChangedEvent("numTotalAReportar");
            }
        }

        public int numTotalAReportar
        {
            get { return encRep.numTotalaReportar; }
            set { encRep.numTotalaReportar = value; RaisePropertyChangedEvent("numTotalAReportar"); }
        }

        public DateTime dtmFechaReporte
        {
            get { return encRep.dtmFecha; }
            set { encRep.dtmFecha = value; RaisePropertyChangedEvent("dtmFechaReporte"); }
        }

        private List<CLSMAEEMPP> lisempleados = new List<CLSMAEEMPP>();

        private VMbuscarGeneral _buscarEmpleado;
        public VMbuscarGeneral buscarEmpleado
        {
            get { return _buscarEmpleado; }
            set { _buscarEmpleado = value; base.OnPropertyChanged("buscarEmpleado"); }
        }

        private string _strTituloVentana;
        public string strTituloVentana
        {
            get { return _strTituloVentana; }
            set { _strTituloVentana = value; base.OnPropertyChanged("strTituloVentana"); }
        }

        #endregion propiedades

        #region metodos

        private void consultarRPP()
        {
            try
            {
                _repositorio.consultarRPP(opciones);
            }
            catch(Exception ex)
            { MessageBox.Show(ex.Message); }
        }

        private void consultarSemana(string sw)
        {
            try
            {
                _repositorio.consultarSemana(encRep,sw);
                RaisePropertyChangedEvent("numSemana");
                RaisePropertyChangedEvent("dtmDesde");
                RaisePropertyChangedEvent("dtmHasta");
            }
            catch (Exception ex)
            { MessageBox.Show(ex.Message); }
        }

        public void ConsultarOperarios()
        {
            try
            {
                clases.CLSMAEEMPP datos = new clases.CLSMAEEMPP();
                produccion.forms.FRMbuscar frm = new produccion.forms.FRMbuscar(datos, "buscar", "Nombre_Empleado", "NOMEMP_EMP", "Codigo");
                frm.ShowDialog();
                encRep.selOperario.strOperario = frm.retorno;
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }

        public void guardar() 
        {
            try 
            {
                encRep.validarErrorOperario();
                if (encRep.logErrorOperarios == false && encRep.logErrorOperarios2 == false)
                {
                    encRep.validarErrorTallas();
                    if (encRep.logErrorTallas == false)
                    {
                        if (_repositorio.guardarRepPrcesoPro(encRep))
                        {
                            encRep.msn.tipo = true;
                            limpiar();
                            encRep.msn.texto = "Reporte guardado con exito.";
                        }
                        else
                        {
                            encRep.msn.texto = "Reporte no puedo ser guardado.";
                            encRep.msn.tipo = false;
                        }
                    }
                    else
                    {
                        encRep.msn.texto = "No se puede grabar. Hay errores en las tallas.";
                        encRep.msn.tipo = false;
                    }
                }
                else
                {
                    encRep.msn.texto = "No se puede grabar. Hay error en los operarios o en los porcentajes.";
                    encRep.msn.tipo = false;
                }

            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }

        void limpiar()
        {
            try
            {
                encRep.dttallas.Clear();
                encRep.listallas.Clear();
                encRep.dtReportados.Clear();
                encRep.detOperario.Clear();
                strNumeroOrden = "";
                encRep.strNombreReferencia = null;
                encRep.strNombreColor = null;
                encRep.numTotalPendiente = 0;
                encRep.numTotalReportado = 0;
                encRep.numTotalOrden = 0;
                numTotalAReportar = 0;
                //numConsecutivo = null;
                if (encRep.visorFotoReferencia != null)
                {
                    if (encRep.visorFotoReferencia.strCodigo != null)
                    {
                        encRep.visorFotoReferencia.strCodigo = "";
                        encRep.visorFotoReferencia.strColor = "";
                    }
                }
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }
        void limpiarOrden()
        {
            try
            {
                encRep.dttallas.Clear();
                encRep.listallas.Clear();
                encRep.dtReportados.Clear();
                encRep.detOperario.Clear();
                encRep.strNombreReferencia = null;
                encRep.strNombreColor = null;
                encRep.numTotalPendiente = 0;
                encRep.numTotalReportado = 0;
                encRep.numTotalOrden = 0;
                numTotalAReportar = 0;
                if (encRep.visorFotoReferencia != null)
                {
                    if (encRep.visorFotoReferencia.strCodigo != null)
                    {
                        encRep.visorFotoReferencia.strCodigo = "";
                        encRep.visorFotoReferencia.strColor = "";
                    }
                }
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }

        public void BuscaOperario()
        {
            try
            {
                buscarEmpleado.IsOpen = true;
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }

        public void BuscarOperario(object columna)
        {
            try
            {
                int numColumna = Convert.ToInt32(columna);
                if (numColumna == 0)
                {
                    if (encRep.numSelOperario == encRep.detOperario.Count)
                    {
                        return;
                    }
                    else
                    {
                        clases.CLSMAEEMPP datos = new clases.CLSMAEEMPP();
                        produccion.forms.FRMbuscar frm = new produccion.forms.FRMbuscar(datos, "buscar", "Nombre_Empleado", "NOMEMP_EMP", "Codigo");
                        frm.filtro.Text = encRep.selOperario.strOperario;
                        frm.filtro.Select(encRep.selOperario.strOperario.Length, encRep.selOperario.strOperario.Length);
                        frm.ShowDialog();
                        if (!String.IsNullOrEmpty(frm.retorno))
                        {
                            encRep.selOperario.strOperario = frm.retorno;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        public void Salir(object frmFormulario)
        {
             ((Window)frmFormulario).Close(); 
        }

        void OnBuscarEmpleadoPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "IsOpen")
            {
                if (!buscarEmpleado.IsOpen)
                {
                    if (buscarEmpleado.gridBuscar.selLista != null)
                    {
                        if (encRep.selOperario != null)
                        {
                            encRep.selOperario.strOperario = buscarEmpleado.gridBuscar.selLista.strColumna1;
                        }
                    }
                }
            }
        }

        void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            try
            {
                if (e.NewItems != null && e.NewItems.Count != 0)
                {
                    foreach (MReporteProcProd.operario ope in e.NewItems)
                    {
                        ope.PropertyChanged += OnPropertyChanged;
                    }
                }
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }

        void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            try
            {
                encRep.logErrorOperarios = ((from ope in encRep.detOperario where ope.IsValid.Equals(false) select ope.IsValid).ToList().Count()) > 0 ? true : false;
                if (encRep.logErrorOperarios == false)
                {
                    var items = (from ope in encRep.detOperario where ope.IsValid.Equals(false) select ope.numPorcentaje);
                    int ntotal = Convert.ToInt32(items.Sum());
                    encRep.logErrorOperarios = ntotal != 100 ? true : false;
                }
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }

        void OnCollectionChangedTallas(object sender, NotifyCollectionChangedEventArgs e)
        {
            try
            {
                if (e.NewItems != null && e.NewItems.Count > 0)
                {
                    foreach (MReporteProcProd.tallas tal in e.NewItems)
                    {
                        tal.PropertyChanged += OnPropertyChangedTalla;
                    }
                }

            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }

        void OnPropertyChangedTalla(object sender, PropertyChangedEventArgs e)
        {
            try
            {
                numTotalAReportar = encRep.listallas[0].numTalla1 + encRep.listallas[0].numTalla2 + encRep.listallas[0].numTalla3 + encRep.listallas[0].numTalla4 + encRep.listallas[0].numTalla5 + encRep.listallas[0].numTalla6 + encRep.listallas[0].numTalla7 + encRep.listallas[0].numTalla8 + encRep.listallas[0].numTalla9 + encRep.listallas[0].numTalla10 + encRep.listallas[0].numTalla11 + encRep.listallas[0].numTalla12 + encRep.listallas[0].numTalla13 + encRep.listallas[0].numTalla14 + encRep.listallas[0].numTalla15 + encRep.listallas[0].numTalla16 + encRep.listallas[0].numTalla17 + encRep.listallas[0].numTalla18 + encRep.listallas[0].numTalla19 + encRep.listallas[0].numTalla20;
                RaisePropertyChangedEvent("numTotalAReportar");
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }

        #endregion metodos

        #region IDataErrorInfo Members

        string IDataErrorInfo.Error { get { return null; } }

        string IDataErrorInfo.this[string propertyName]
        {
            get { return this.GetValidationError(propertyName); }
        }

        #endregion

        #region Validation

        /// <summary>
        /// Returns true if this object has no validation errors.
        /// </summary>
        public bool IsValid
        {
            get
            {
                foreach (string property in ValidatedProperties)
                    if (GetValidationError(property) != null)
                        return false;

                return true;
            }
        }

        static readonly string[] ValidatedProperties = 
        { 
            "numConsecutivo", 
            "dtmDesde",
            "dtmHasta",
            "strNumeroOrden",      
            "dtmFechaReporte",
            "numTotalAReportar"
        };

        string GetValidationError(string propertyName)
        {
            if (Array.IndexOf(ValidatedProperties, propertyName) < 0)
                return null;

            string error = null;

            switch (propertyName)
            {
                case "numConsecutivo":
                    error = this.ValidatenumConsecutivo();
                    break;
                case "dtmDesde":
                    error = this.ValidatedtmDesde();
                    break;
                case "dtmHasta":
                    error = this.ValidatedtmHasta();
                    break;  
                case "strNumeroOrden":
                    error = this.ValidatedstrNumeroOrden();
                    break;
                case "dtmFechaReporte":
                    error = this.ValidateddtmFechaReporte();
                    break;
                case "numTotalAReportar":
                    error = this.ValidatednumTotalaReportar();
                    break;
                default:
                    Debug.Fail("Unexpected property being validated on Customer: " + propertyName);
                    break;
            }
            return error;
        }

        string ValidatenumConsecutivo()
        {
            if (numConsecutivo == null)  { return "La opcion no puede estar vacia."; }
            if (numConsecutivo != null)
            {
                if (String.IsNullOrEmpty(numConsecutivo))
                    numConsecutivo = "1";
                int consec = Convert.ToInt32(numConsecutivo);
                if (consec > opciones.Count)
                {
                    selOpcion = new MReporteProcProd.opcion();
                    numConsecutivo = "";
                    return "El proceso no existe.";
                }
            }
            return null;
        }

        string ValidatedtmDesde()
        {
            if (dtmDesde != null)
            {
                if (dtmDesde > dtmHasta) { return "La fecha inicial debe ser menor o igual que la fecha final"; }

                TimeSpan ts = dtmHasta.Subtract(dtmDesde);

                if (ts.Days > 7) { return "El rango de fechas no debe de ser mayor a una semana."; }
            }

            return null;
        }

        string ValidatedtmHasta()
        {
            if (dtmHasta != null)
            {
                if (dtmHasta < dtmDesde) { return "La fecha final debe ser mayor o igual que la fecha inicial"; }

                TimeSpan ts = dtmHasta.Subtract(dtmDesde);
                if (ts.Days > 7) { return "El rango de fechas no debe de ser mayor a una semana."; }
            }
         
            return null;
        }

        string ValidatedstrNumeroOrden() 
        {
            if (strNumeroOrden == null) { return "Debe ingresar la orden de producción"; }
            
            return null;
        }

        string ValidateddtmFechaReporte()
        {
            if (dtmFechaReporte == null) { return "La fecha del reporte no puede estar vacia";  }

            return null;
        }

        string ValidatednumTotalaReportar()
        {
            if (numTotalAReportar < 1) { return "La cantidad a reportar debe ser mayor que cero"; }
            if (numTotalAReportar > encRep.numTotalPendiente) { return "La cantidad a reportar no puede ser mayor a la cantidad pendiente"; }
            
            return null;
        }

        #endregion
    }
}
